package com.example.myblog.config;

import cn.hutool.core.util.StrUtil;
import com.example.myblog.dto.UserDTO;
import com.example.myblog.exception.BaseException;
import com.example.myblog.result.BaseCodeEnum;
import com.example.myblog.utils.RedisUtils;
import com.example.myblog.utils.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

import static com.example.myblog.constants.RedisConstants.*;

/**
 * @author yx
 */
@Configuration
public class LoginConfig implements WebMvcConfigurer {
    RedisUtils redisUtils;

    @Autowired
    public void setRedisUtils(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        String[] paths = {"/login/**",
                "/register/**",
                "/blog/pages",
                "/blog-message/blogs",
                "/site"};
        // 设置一些无需登录权限校验的路径
        registry.addInterceptor(new LoginInterceptor()).excludePathPatterns(paths);

        registry.addInterceptor(new NextInterceptor()).addPathPatterns("/**").excludePathPatterns(
                paths
        );
    }

    /**
     * 登录拦截器
     */
    class LoginInterceptor implements HandlerInterceptor{
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                if ( HttpMethod.OPTIONS.matches(request.getMethod())) {
                    return true;
                }
                // 1.判断请求头是否携带 token
                String token = request.getHeader("Authorization");
                // 2.未携带则清空ThreadLocal中的UserDTO放行给后面拦截器拦截
                System.out.println(token);
                if (StrUtil.isBlank(token)) {
                    UserThreadLocal.clearUserDto();
                    return true;
                }
                System.out.println("\t\t\t"+request.getRequestURL());
                // 3.已携带 token 证明登录过，获取 Redis 中的用户信息
                String tokenKey = USER_LOGIN_KEY + token;
                UserDTO userDTO = redisUtils.getValueByHash(tokenKey, new UserDTO());
                // 4.存入 ThreadLocal 中
                UserThreadLocal.setUserDto(userDTO);
                // 5.刷新 Redis 中 token 的有效期
                redisUtils.expire(tokenKey,USER_LOGIN_TTL, TimeUnit.MINUTES);
                return true;
            }




    }

    /**
     * 后置拦截处理器
     */
    class NextInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            if ( HttpMethod.OPTIONS.matches(request.getMethod())) {
                return true;
            }
            if (UserThreadLocal.getUserDto() == null) {
                throw new BaseException(BaseCodeEnum.NO_AUTH);
            }
            return true;
        }
    }

}
